package sk.gtug.pivoplus.malepivo.utils;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Locale;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;

import sk.gtug.pivoplus.malepivo.Application;
import sk.gtug.pivoplus.malepivo.model.GeocodeResponse;
import sk.gtug.pivoplus.malepivo.model.GeocodeResponseResult;
import sk.gtug.pivoplus.malepivo.model.GeocodeResponseResult.GeocodeResponseResultColumns;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;

import com.google.gson.Gson;

public class LocationHelper {

	private Context mContext;
	private IMakeAddressRequestCallback mAddressRequestCallback;

	private static String GMAPS_ADDR_URI     = "http://maps.googleapis.com/maps/api/geocode/json?address=%s&language=%s&sensor=false";
	private static String GMAPS_ADDR_REV_URI = "http://maps.googleapis.com/maps/api/geocode/json?latlng=%s,%s&language=%s&sensor=false";

	public LocationHelper(Context context) {
		mContext = context;
	}

	public void updateLocation() {

		SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
		String cityValue    = preferences.getString(Application.PREFS_KEY_CITY, null);
		String countryValue = preferences.getString(Application.PREFS_KEY_COUNTRY, null);

		if (cityValue != null && countryValue != null) {
			return;
		}

/*		LocationManager lm = (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE);
		Criteria crit = new Criteria();
		crit.setAccuracy(Criteria.ACCURACY_FINE);
		String provider = lm.getBestProvider(crit, true);
		Location loc = lm.getLastKnownLocation(provider);
		if (loc == null){
			crit.setAccuracy(Criteria.ACCURACY_COARSE);
			provider = lm.getBestProvider(crit, true);
			loc = lm.getLastKnownLocation(provider); 	 		
		}*/

		Location loc = getActualPosition();
		if (loc != null) {
			MakeLocationRequest(String.valueOf(loc.getLatitude()), String.valueOf(loc.getLongitude()));
		} else {
			Toast.makeText(mContext, "Locality unavailable", Toast.LENGTH_SHORT).show();
		}
	}

	public Location getActualPosition() {
		LocationManager lm = (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE);
		Criteria crit = new Criteria();
		crit.setAccuracy(Criteria.ACCURACY_FINE);
		String provider = lm.getBestProvider(crit, true);
		Location loc = lm.getLastKnownLocation(provider);
		if (loc == null){
			crit.setAccuracy(Criteria.ACCURACY_COARSE);
			provider = lm.getBestProvider(crit, true);
			loc = lm.getLastKnownLocation(provider); 	 		
		}
		return loc;
	}

	private GeocodeResponse makeRequest(Context cnt, URL url) {	
		Reader reader;
		HttpClient httpclient = new DefaultHttpClient();
				
		try {
			HttpUriRequest request = new HttpGet(url.toURI());
			
			HttpResponse response = httpclient.execute(request);
			
			reader = new InputStreamReader(response.getEntity().getContent());
			Gson gson = new Gson();        

	        GeocodeResponse result = gson.fromJson(reader, GeocodeResponse.class);    
	        reader.close();
	        return result;
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}

	private GeocodeResponse getResponseByAddress(Context cnt, String adress) {
		URL url;
		try {
			url = new URL(String.format(GMAPS_ADDR_URI, URLEncoder.encode(adress), Locale.getDefault().getLanguage()));
			return makeRequest(cnt, url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return null;
	}

	private GeocodeResponse getResponseByLocation(Context cnt, String lat, String lng) {
		URL url;
		try {
			url = new URL(String.format(GMAPS_ADDR_REV_URI, URLEncoder.encode(lat), URLEncoder.encode(lng), Locale.getDefault().getLanguage()));
			return makeRequest(cnt, url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void MakeAddressRequest(String address, IMakeAddressRequestCallback callback) {
		mAddressRequestCallback = callback;
		new MakeAdressRequestTask().execute(address);
	}

	public interface IMakeAddressRequestCallback {
		public void onRequestFinished(GeocodeResponse result);
	}

	private class MakeAdressRequestTask extends AsyncTask<String, Void, GeocodeResponse> {
		
		protected void onPreExecute() {
		}
		
		protected GeocodeResponse doInBackground(String... adress) {
			return getResponseByAddress(mContext ,adress[0]);
		}

	     protected void onPostExecute(GeocodeResponse result) {
	    	 Log.d("task", "remove footer");
	    	 if (result != null && result.results.size() > 0){
//	    		 ((TextView) findViewById(R.id.text1)).setText(result.results.get(0).formatted_address);
//	    		 ((TextView) findViewById(R.id.text2)).setText(result.results.get(0).getAdressComponentType(GeocodeResponseResultColumns.ADMINISTRATIVE_AREA_LEVEL_1));
//	    		 ((TextView) findViewById(R.id.text3)).setText(result.results.get(0).geometry.location.lat + ", " + result.results.get(0).geometry.location.lng);
	    		 
//	    		 List<String> locations = new ArrayList<String>();
//	    		 for(GeocodeResponseResult item : result.results){
//	    			 locations.add(item.formatted_address);
//	    		 }
	    		 if (mAddressRequestCallback != null) {
	    			 mAddressRequestCallback.onRequestFinished(result);
	    			 mAddressRequestCallback = null;
	    		 }
	    		 
//	    		 ArrayAdapter<String> adapter = new ArrayAdapter<String>(LocationNew.this, R.layout.auto_complete_item, R.id.text1, locations.toArray(new String[]{}));
//	    		 ((AutoCompleteTextView) findViewById(R.id.name_field)).setAdapter(adapter);
//	    		 ((AutoCompleteTextView) findViewById(R.id.name_field)).showDropDown();
	    	 }
	     }
	}
	
	public void MakeLocationRequest(String lat, String lng){
		new MakeLocationRequestTask().execute(lat, lng);
	}
	
	private class MakeLocationRequestTask extends AsyncTask<String, Void, GeocodeResponse> {
		
		 protected void onPreExecute() {
			 
		 }
		
	     protected GeocodeResponse doInBackground(String... location) {
	         return getResponseByLocation(mContext ,location[0], location[1]);
	     }

	     protected void onPostExecute(GeocodeResponse result) {
	    	 Log.d("task", "remove footer");
	    	 if (result != null && result.results.size() > 0) {
				GeocodeResponseResult locality = result.getLocality();
				if (locality == null) {
					return;
				}

				SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
				SharedPreferences.Editor editor = preferences.edit();
				editor.putString(Application.PREFS_KEY_CITY, locality.getAdressComponentType(GeocodeResponseResultColumns.LOCALITY));
				editor.putString(Application.PREFS_KEY_COUNTRY, locality.getAdressComponentType(GeocodeResponseResultColumns.COUNTRY));
				editor.commit();

				Toast.makeText(mContext, "Locality set to: " + locality.getAdressComponentType(GeocodeResponseResultColumns.LOCALITY), Toast.LENGTH_SHORT).show();
	    	 }
	     }
	 }
	
}
